1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 module hip.event.dispatcher;
12 private:
13     import hip.event.handlers.keyboard;
14     import hip.event.handlers.mouse;
15     import hip.systems.gamepad;
16     import hip.windowing.window;
17 
18 public:
19     import hip.systems.input;
20     import hip.util.time;
21     import hip.api.input.keyboard;
22     import hip.api.input.button;
23     import hip.api.input.mouse;
24     import hip.api.input.gamepad;
25 
26 
27 
28 package __gshared HipGamepad[] gamepads;
29 
30 
31 /** 
32  * Class used to dispatch the events for the each specific handler.
33  *
34  *  In the entire engine, there must be only one dispatcher. But it is possible
35  *  to create more mouses and keyboards, but it is not being used yet.
36  */
37 class EventDispatcher
38 {
39     ulong frameCount;
40     KeyboardHandler keyboard = null;
41     HipMouse mouse = null;
42     HipWindow window;
43     protected void delegate(uint width, uint height)[] resizeListeners;
44 
45     this(HipWindow window)
46     {
47         this.window = window;
48         keyboard = new KeyboardHandler();
49         mouse = new HipMouse();
50         HipEventQueue.newController(); //Creates controller 0
51         initGamepads();
52         import hip.windowing.events;
53 
54         onKeyDown = (uint key)
55         {
56             try
57             {
58                 HipEventQueue.post(0, HipEventQueue.EventType.keyDown, HipEventQueue.Key(getHipKeyFromSystem(key)));
59             }
60             catch(Exception e){assert(false);}
61         };
62         onKeyUp = (uint key)
63         {
64             try{HipEventQueue.post(0, HipEventQueue.EventType.keyUp, HipEventQueue.Key(getHipKeyFromSystem(key)));}
65             catch(Exception e){assert(false);}
66         };
67         onMouseMove = (int x, int y)
68         {
69             try{HipEventQueue.post(0, HipEventQueue.EventType.touchMove, HipEventQueue.Touch(0, x, y));}
70             catch(Exception e){assert(false);}
71         };
72         onMouseUp = (ubyte btn, int x, int y)
73         {
74             try{HipEventQueue.post(0, HipEventQueue.EventType.touchUp, HipEventQueue.Touch(0, x, y));}
75             catch(Exception e){assert(false);}
76         };
77         onMouseDown = (ubyte btn, int x, int y)
78         {
79             try{HipEventQueue.post(0, HipEventQueue.EventType.touchDown, HipEventQueue.Touch(0, x, y));}
80             catch(Exception e){assert(false);}
81         };
82         onMouseWheel = (int moveX, int moveY)
83         {
84             try{HipEventQueue.post(0, HipEventQueue.EventType.touchScroll, HipEventQueue.Scroll(moveX, moveY, 0));}
85             catch(Exception e){assert(false);}
86         };
87 
88         onWindowResize = (uint width, uint height)
89         {
90             try{HipEventQueue.post(0, HipEventQueue.EventType.windowResize, HipEventQueue.Resize(width, height));}
91             catch(Exception e){assert(false);}
92         };
93         onWindowClosed = ()
94         {
95             try{HipEventQueue.post(0, HipEventQueue.EventType.exit, true);}
96             catch(Exception e){assert(false);}
97         };
98 
99     }
100     
101     bool hasQuit = false;
102 
103     void handleEvent()
104     {
105         window.pollWindowEvents();
106         handleHipEvent();
107         frameCount++;
108     }
109 
110 
111     void handleHipEvent()
112     {
113         
114         //Now poll the cross platform input queue
115         HipEventQueue.InputEvent* ev;
116         while((ev = HipEventQueue.poll(0)) != null)
117         {
118             switch(ev.type)
119             {
120                 case HipEventQueue.EventType.windowResize:
121                     auto w = ev.get!(HipEventQueue.Resize);
122                     foreach(r; resizeListeners)
123                         r(w.width, w.height);
124                     break;
125                 case HipEventQueue.EventType.touchDown:
126                     auto t = ev.get!(HipEventQueue.Touch);
127                     mouse.setPosition(t.xPos, t.yPos, t.id);
128                     mouse.setPressed(HipMouseButton.left, true);
129                     break;
130                 case HipEventQueue.EventType.touchUp:
131                     auto t = ev.get!(HipEventQueue.Touch);
132                     mouse.setPosition(t.xPos, t.yPos, t.id);
133                     mouse.setPressed(HipMouseButton.left, false);
134                     break;
135                 case HipEventQueue.EventType.touchMove:
136                     auto t = ev.get!(HipEventQueue.Touch);
137                     mouse.setPosition(t.xPos, t.yPos, t.id);
138                     break;
139                 case HipEventQueue.EventType.touchScroll:
140                     auto t = ev.get!(HipEventQueue.Scroll);
141                     mouse.setScroll(t.x, t.y, t.z);
142                     break;
143                 case HipEventQueue.EventType.keyDown:
144                 import hip.console.log;
145                     auto k = ev.get!(HipEventQueue.Key);
146                     keyboard.handleKeyDown(cast(HipKey)(k.id));
147                     break;
148                 case HipEventQueue.EventType.keyUp:
149                     auto k = ev.get!(HipEventQueue.Key);
150                     keyboard.handleKeyUp(cast(HipKey)(k.id));
151                     break;
152                 case HipEventQueue.EventType.gamepadConnected:
153                     import hip.console.log;rawlog("Gamepad connected");
154                     auto g = ev.get!(HipEventQueue.Gamepad);
155                     if(g.id+1 > gamepads.length)
156                         gamepads~= getNewGamepad(g.type);
157                     gamepads[g.id].setConnected(true);
158                     break;
159                 case HipEventQueue.EventType.gamepadDisconnected:
160                     import hip.console.log;rawlog("Gamepad disconnected");
161                     auto g = ev.get!(HipEventQueue.Gamepad);
162                     gamepads[g.id].setConnected(false);
163                     break;
164                 case HipEventQueue.EventType.exit:
165                     hasQuit = true;
166                     break;
167                 default:break;
168             }
169         }
170         
171         keyboard.update();
172     }
173     void pollGamepads(float deltaTime)
174     {
175         foreach (g; gamepads)
176             g.poll(deltaTime);
177     }
178 
179     void addOnResizeListener(void delegate(uint width, uint height) onResize)
180     in{assert(onResize !is null, "onResize event must not be null.");}
181     do
182     {
183         resizeListeners~= onResize;    
184     }
185 
186     ///Public API
187     Vector2 getTouchPosition(uint id = 0){return mouse.getPosition(id);}
188     Vector2 getTouchDeltaPosition(uint id = 0){return mouse.getDeltaPosition(id);}
189     ubyte getMulticlickCount(HipMouseButton btn = HipMouseButton.any, uint id = 0){return mouse.getMulticlickCount(btn);}
190     bool isDoubleClicked(HipMouseButton btn = HipMouseButton.any, uint id = 0){return mouse.isDoubleClicked(btn);}
191     bool isMouseButtonPressed(HipMouseButton btn = HipMouseButton.any, uint id = 0){return mouse.isPressed(btn);}
192     bool isMouseButtonJustPressed(HipMouseButton btn = HipMouseButton.any, uint id = 0){return mouse.isJustPressed(btn);}
193     bool isMouseButtonJustReleased(HipMouseButton btn = HipMouseButton.any, uint id = 0){return mouse.isJustReleased(btn);}
194     Vector3 getScroll(){return mouse.getScroll();}
195     bool isKeyPressed(char key, uint id = 0){return keyboard.isKeyPressed(key.toUppercase);}
196     bool isKeyJustPressed(char key, uint id = 0){return keyboard.isKeyJustPressed(key.toUppercase);}
197     bool isKeyJustReleased(char key, uint id = 0){return keyboard.isKeyJustReleased(key.toUppercase);}
198     float getKeyDownTime(char key, uint id = 0){return keyboard.getKeyDownTime(key.toUppercase);}
199     float getKeyUpTime(char key, uint id = 0){return keyboard.getKeyUpTime(key.toUppercase);}
200     ubyte getGamepadCount(){return cast(ubyte)gamepads.length;}
201     AHipGamepad getGamepad(ubyte id)
202     {
203         if(id >= gamepads.length)return null;
204         return gamepads[id];
205     }
206     Vector3 getAnalog(HipGamepadAnalogs analog, ubyte id = 0)
207     {
208         if(id >= gamepads.length) return Vector3.zero;
209         return gamepads[id].getAnalogState(analog);
210     }
211     bool isGamepadButtonPressed(HipGamepadButton btn, ubyte id = 0)
212     {
213         if(id >= gamepads.length) return false;
214         return gamepads[id].isButtonPressed(btn);
215     }
216     bool isGamepadButtonJustPressed(HipGamepadButton btn, ubyte id = 0)
217     {
218         if(id >= gamepads.length) return false;
219         return gamepads[id].isButtonJustPressed(btn);
220     }
221     bool isGamepadButtonJustReleased(HipGamepadButton btn, ubyte id = 0)
222     {
223         if(id >= gamepads.length) return false;
224         return gamepads[id].isButtonJustReleased(btn);
225     }
226 
227     bool areGamepadButtonsPressed(scope HipGamepadButton[] btns, ubyte id = 0)
228     {
229         if(id >= gamepads.length) return false;
230         return gamepads[id].areButtonsPressed(btns);
231     }
232     bool areGamepadButtonsJustPressed(scope HipGamepadButton[] btns, ubyte id = 0)
233     {
234         if(id >= gamepads.length) return false;
235         return gamepads[id].areButtonsJustPressed(btns);
236     }
237     bool areGamepadButtonsJustReleased(scope HipGamepadButton[] btns, ubyte id = 0)
238     {
239         if(id >= gamepads.length) return false;
240         return gamepads[id].areButtonsJustReleased(btns);
241     }
242     
243     bool isGamepadWireless(ubyte id = 0)
244     {
245         if(id >= gamepads.length) return false;
246         return gamepads[id].isWireless();
247     }
248     bool setGamepadVibrating(float vibrationPower, float time, ubyte id = 0)
249     {
250         if(id >= gamepads.length) return false;
251         return gamepads[id].setVibrating(vibrationPower, time);
252     }
253     float getGamepadBatteryStatus(ubyte id = 0)
254     {
255         if(id >= gamepads.length) return 0;
256         return gamepads[id].getBatteryStatus();
257     }
258 
259     void postUpdate()
260     {
261         keyboard.postUpdate();
262         mouse.postUpdate();
263         foreach(g; gamepads)
264             g.postUpdate();
265     }
266 }
267 
268 
269 version(Windows)
270 {
271     public HipKey getHipKeyFromSystem(uint key)
272     {
273         import core.sys.windows.winuser;
274         ushort k = cast(ushort)(key);
275         assert(k > 0 && k <= ubyte.max, "Key out of range");
276         switch(k)
277         {
278             case VK_BACK: return HipKey.BACKSPACE;
279             case VK_TAB: return HipKey.TAB;
280             case VK_ESCAPE: return HipKey.ESCAPE;
281 
282 
283             case VK_SHIFT: return HipKey.SHIFT;
284             case VK_CONTROL: return HipKey.CTRL;
285             case VK_MENU: return HipKey.ALT;
286             case VK_SNAPSHOT: return HipKey.PRINT;
287             
288             case VK_RETURN: return HipKey.ENTER;
289             case VK_CAPITAL: return HipKey.CAPSLOCK;
290             case VK_SPACE: return HipKey.SPACE;
291             case VK_PRIOR: return HipKey.PAGE_UP;
292             case VK_NEXT: return HipKey.PAGE_UP;
293             case VK_END: return HipKey.END;
294             case VK_HOME: return HipKey.HOME;
295             case VK_LEFT: return HipKey.ARROW_LEFT;
296             case VK_UP: return HipKey.ARROW_UP;
297             case VK_RIGHT: return HipKey.ARROW_RIGHT;
298             case VK_DOWN: return HipKey.ARROW_DOWN;
299             case VK_INSERT: return HipKey.INSERT;
300             case VK_DELETE: return HipKey.DELETE;
301             //0
302             case 0x30: return HipKey._0;
303             case 0x31: return HipKey._1;
304             case 0x32: return HipKey._2;
305             case 0x33: return HipKey._3;
306             case 0x34: return HipKey._4;
307             case 0x35: return HipKey._5;
308             case 0x36: return HipKey._6;
309             case 0x37: return HipKey._7;
310             case 0x38: return HipKey._8;
311             case 0x39: return HipKey._9;
312             //A
313             case 0x41: return HipKey.A;
314             case 0x42: return HipKey.B;
315             case 0x43: return HipKey.C;
316             case 0x44: return HipKey.D;
317             case 0x45: return HipKey.E;
318             case 0x46: return HipKey.F;
319             case 0x47: return HipKey.G;
320             case 0x48: return HipKey.H;
321             case 0x49: return HipKey.I;
322             case 0x4A: return HipKey.J;
323             case 0x4B: return HipKey.K;
324             case 0x4C: return HipKey.L;
325             case 0x4D: return HipKey.M;
326             case 0x4E: return HipKey.N;
327             case 0x4F: return HipKey.O;
328             case 0x50: return HipKey.P;
329             case 0x51: return HipKey.Q;
330             case 0x52: return HipKey.R;
331             case 0x53: return HipKey.S;
332             case 0x54: return HipKey.T;
333             case 0x55: return HipKey.U;
334             case 0x56: return HipKey.V;
335             case 0x57: return HipKey.W;
336             case 0x58: return HipKey.X;
337             case 0x59: return HipKey.Y;
338             case 0x5A: return HipKey.Z;
339             case VK_LWIN: return HipKey.META_LEFT;
340             case VK_RWIN: return HipKey.META_RIGHT;
341             //Maybe there's a need to change?
342             case VK_NUMPAD0: return HipKey._0;
343             case VK_NUMPAD1: return HipKey._1;
344             case VK_NUMPAD2: return HipKey._2;
345             case VK_NUMPAD3: return HipKey._3;
346             case VK_NUMPAD4: return HipKey._4;
347             case VK_NUMPAD5: return HipKey._5;
348             case VK_NUMPAD6: return HipKey._6;
349             case VK_NUMPAD7: return HipKey._7;
350             case VK_NUMPAD8: return HipKey._8;
351             case VK_NUMPAD9: return HipKey._9;
352 
353             case VK_F1: return HipKey.F1;
354             case VK_F2: return HipKey.F2;
355             case VK_F3: return HipKey.F3;
356             case VK_F4: return HipKey.F4;
357             case VK_F5: return HipKey.F5;
358             case VK_F6: return HipKey.F6;
359             case VK_F7: return HipKey.F7;
360             case VK_F8: return HipKey.F8;
361             case VK_F9: return HipKey.F9;
362             case VK_F10: return HipKey.F10;
363             case VK_F11: return HipKey.F11;
364             case VK_F12: return HipKey.F12;
365 
366             case VK_LSHIFT: return HipKey.SHIFT;
367             case VK_RSHIFT: return HipKey.SHIFT;
368 
369             case VK_LCONTROL: return HipKey.CTRL;
370             case VK_RCONTROL: return HipKey.CTRL;
371             
372             case VK_LMENU: return HipKey.ALT;
373             case VK_RMENU: return HipKey.ALT;
374 
375             case VK_OEM_1: return HipKey.SEMICOLON;
376 
377             case VK_OEM_COMMA: return HipKey.COMMA;
378             case VK_OEM_MINUS: return HipKey.MINUS;
379             case VK_OEM_PERIOD: return HipKey.PERIOD;
380 
381             case VK_OEM_2: return HipKey.SLASH;
382             
383             case VK_OEM_4: return HipKey.BRACKET_LEFT;
384             case VK_OEM_5: return HipKey.BACKSLASH;
385             case VK_OEM_6: return HipKey.BRACKET_RIGHT;
386             case VK_OEM_7: return HipKey.QUOTE;
387             case  0xFF: return HipKey.NONE; //Invalid
388 
389             default:
390                 version(HipCheckUnknownKeycode)
391                 {
392                     import hip.util.conv:to;
393                     assert(false, "Unknown key received ("~to!string(k)~")");
394                 }
395                 else
396                     return cast(HipKey)k;
397         }
398     }
399 }
400 else version(linux)
401 {
402     public HipKey getHipKeyFromSystem(uint key)
403     {
404         import hip.windowing.platforms.x11lib.keysym;
405         switch(key)
406         {
407             case XK_BackSpace: return HipKey.BACKSPACE;
408             case XK_Tab: return HipKey.TAB;
409             case XK_Return: return HipKey.ENTER;
410             case XK_KP_Enter: return HipKey.ENTER;
411             case XK_Shift_L: return HipKey.SHIFT;
412             case XK_Shift_R: return HipKey.SHIFT;
413             case XK_Control_L: return HipKey.CTRL;
414             case XK_Control_R: return HipKey.CTRL;
415             case XK_Alt_L: return HipKey.ALT;
416             case XK_Alt_R: return HipKey.ALT;
417             case XK_Pause: return HipKey.PAUSE_BREAK;
418             case XK_Caps_Lock: return HipKey.CAPSLOCK;
419             case XK_Escape: return HipKey.ESCAPE;
420             case XK_space: return HipKey.SPACE;
421             case XK_Page_Up: return HipKey.PAGE_UP;
422             case XK_Page_Down: return HipKey.PAGE_DOWN;
423             case XK_End: return HipKey.END;
424             case XK_Home: return HipKey.HOME;
425             case XK_Left: return HipKey.ARROW_LEFT;
426             case XK_Up: return HipKey.ARROW_UP;
427             case XK_Right: return HipKey.ARROW_RIGHT;
428             case XK_Down: return HipKey.ARROW_DOWN;
429             case XK_Insert: return HipKey.INSERT;
430             case XK_Delete: return HipKey.DELETE;
431             case XK_0: return HipKey._0;
432             case XK_1: return HipKey._1;
433             case XK_2: return HipKey._2;
434             case XK_3: return HipKey._3;
435             case XK_4: return HipKey._4;
436             case XK_5: return HipKey._5;
437             case XK_6: return HipKey._6;
438             case XK_7: return HipKey._7;
439             case XK_8: return HipKey._8;
440             case XK_9: return HipKey._9;
441             case XK_A: return HipKey.A;
442             case XK_B: return HipKey.B;
443             case XK_C: return HipKey.C;
444             case XK_D: return HipKey.D;
445             case XK_E: return HipKey.E;
446             case XK_F: return HipKey.F;
447             case XK_G: return HipKey.G;
448             case XK_H: return HipKey.H;
449             case XK_I: return HipKey.I;
450             case XK_J: return HipKey.J;
451             case XK_K: return HipKey.K;
452             case XK_L: return HipKey.L;
453             case XK_M: return HipKey.M;
454             case XK_N: return HipKey.N;
455             case XK_O: return HipKey.O;
456             case XK_P: return HipKey.P;
457             case XK_Q: return HipKey.Q;
458             case XK_R: return HipKey.R;
459             case XK_S: return HipKey.S;
460             case XK_T: return HipKey.T;
461             case XK_U: return HipKey.U;
462             case XK_V: return HipKey.V;
463             case XK_W: return HipKey.W;
464             case XK_X: return HipKey.X;
465             case XK_Y: return HipKey.Y;
466             case XK_Z: return HipKey.Z;
467             case XK_a: return HipKey.A;
468             case XK_b: return HipKey.B;
469             case XK_c: return HipKey.C;
470             case XK_d: return HipKey.D;
471             case XK_e: return HipKey.E;
472             case XK_f: return HipKey.F;
473             case XK_g: return HipKey.G;
474             case XK_h: return HipKey.H;
475             case XK_i: return HipKey.I;
476             case XK_j: return HipKey.J;
477             case XK_k: return HipKey.K;
478             case XK_l: return HipKey.L;
479             case XK_m: return HipKey.M;
480             case XK_n: return HipKey.N;
481             case XK_o: return HipKey.O;
482             case XK_p: return HipKey.P;
483             case XK_q: return HipKey.Q;
484             case XK_r: return HipKey.R;
485             case XK_s: return HipKey.S;
486             case XK_t: return HipKey.T;
487             case XK_u: return HipKey.U;
488             case XK_v: return HipKey.V;
489             case XK_w: return HipKey.W;
490             case XK_x: return HipKey.X;
491             case XK_y: return HipKey.Y;
492             case XK_z: return HipKey.Z;
493             case XK_Meta_L: return HipKey.META_LEFT;
494             case XK_Meta_R: return HipKey.META_RIGHT;
495             case XK_F1: return HipKey.F1;
496             case XK_F2: return HipKey.F2;
497             case XK_F3: return HipKey.F3;
498             case XK_F4: return HipKey.F4;
499             case XK_F5: return HipKey.F5;
500             case XK_F6: return HipKey.F6;
501             case XK_F7: return HipKey.F7;
502             case XK_F8: return HipKey.F8;
503             case XK_F9: return HipKey.F9;
504             case XK_F10: return HipKey.F10;
505             case XK_F11: return HipKey.F11;
506             case XK_F12: return HipKey.F12;
507             case XK_semicolon: return HipKey.SEMICOLON;
508             case XK_equal: return HipKey.EQUAL;
509             case XK_comma: return HipKey.COMMA;
510             case XK_minus: return HipKey.MINUS;
511             case XK_period: return HipKey.PERIOD;
512             case XK_slash: return HipKey.SLASH;
513             case XK_bracketleft: return HipKey.BRACKET_LEFT;
514             case XK_bracketright: return HipKey.BRACKET_RIGHT;
515             case XK_backslash: return HipKey.BACKSLASH;
516             case XK_grave: return HipKey.QUOTE;
517             default:
518             {
519                 version(HipCheckUnknownKeycode)
520                 {
521                     import hip.util.conv:to;
522                     import hip.error.handler;
523                     ErrorHandler.assertExit(false, "Unknown key received ("~to!string(key)~")");
524                     return cast(HipKey)0;
525                 }
526                 else
527                     return cast(HipKey)key;
528             }
529         }
530     }
531 }
532 else version(WebAssembly)
533 {
534     public HipKey getHipKeyFromSystem(uint key)
535     {
536         ushort k = cast(ushort)(key);
537         assert(k > 0 && k <= ubyte.max, "Key out of range");
538         switch(k)
539         {
540             case 8: return HipKey.BACKSPACE;
541             case 9: return HipKey.TAB;
542             case 27: return HipKey.ESCAPE;
543 
544             
545             case 13: return HipKey.ENTER;
546             case 20: return HipKey.CAPSLOCK;
547             case 32: return HipKey.SPACE;
548             case 33: return HipKey.PAGE_UP;
549             case 35: return HipKey.END;
550             case 36: return HipKey.HOME;
551             case 37: return HipKey.ARROW_LEFT;
552             case 38: return HipKey.ARROW_UP;
553             case 39: return HipKey.ARROW_RIGHT;
554             case 40: return HipKey.ARROW_DOWN;
555             case 45: return HipKey.INSERT;
556             case 46: return HipKey.DELETE;
557             //0
558             case 48: return HipKey._0;
559             case 49: return HipKey._1;
560             case 50: return HipKey._2;
561             case 51: return HipKey._3;
562             case 52: return HipKey._4;
563             case 53: return HipKey._5;
564             case 54: return HipKey._6;
565             case 55: return HipKey._7;
566             case 56: return HipKey._8;
567             case 57: return HipKey._9;
568             //A
569             case 65: return HipKey.A;
570             case 66: return HipKey.B;
571             case 67: return HipKey.C;
572             case 68: return HipKey.D;
573             case 69: return HipKey.E;
574             case 70: return HipKey.F;
575             case 71: return HipKey.G;
576             case 72: return HipKey.H;
577             case 73: return HipKey.I;
578             case 74: return HipKey.J;
579             case 75: return HipKey.K;
580             case 76: return HipKey.L;
581             case 77: return HipKey.M;
582             case 78: return HipKey.N;
583             case 79: return HipKey.O;
584             case 80: return HipKey.P;
585             case 81: return HipKey.Q;
586             case 82: return HipKey.R;
587             case 83: return HipKey.S;
588             case 84: return HipKey.T;
589             case 85: return HipKey.U;
590             case 86: return HipKey.V;
591             case 87: return HipKey.W;
592             case 88: return HipKey.X;
593             case 89: return HipKey.Y;
594             case 90: return HipKey.Z;
595             case 91: return HipKey.META_LEFT;
596             case 93: return HipKey.META_RIGHT;
597             //Maybe there's a need to change?
598             case 97: return HipKey._0;
599             case 98: return HipKey._1;
600             case 99: return HipKey._2;
601             case 100: return HipKey._3;
602             case 101: return HipKey._4;
603             case 102: return HipKey._5;
604             case 103: return HipKey._6;
605             case 104: return HipKey._7;
606             case 105: return HipKey._8;
607             case 106: return HipKey._9;
608 
609             case 112: return HipKey.F1;
610             case 113: return HipKey.F2;
611             case 114: return HipKey.F3;
612             case 115: return HipKey.F4;
613             case 116: return HipKey.F5;
614             case 117: return HipKey.F6;
615             case 118: return HipKey.F7;
616             case 119: return HipKey.F8;
617             case 120: return HipKey.F9;
618             case 121: return HipKey.F10;
619             case 122: return HipKey.F11;
620             case 123: return HipKey.F12;
621 
622             case 16: return HipKey.SHIFT;
623             case 17: return HipKey.CTRL;
624             case 18: return HipKey.ALT;
625 
626             case 191: return HipKey.SEMICOLON;
627 
628             case 188: return HipKey.COMMA;
629             case 189: return HipKey.MINUS;
630             case 190: return HipKey.PERIOD;
631 
632             case 193: return HipKey.SLASH;
633             
634             case 221: return HipKey.BRACKET_LEFT;
635             case 220: return HipKey.BRACKET_RIGHT;
636             case 226: return HipKey.BACKSLASH;
637             case 192: return HipKey.QUOTE;
638             case  0xFF: return HipKey.NONE; //Invalid
639 
640             default:
641                 version(HipCheckUnknownKeycode)
642                 {
643                     import hip.util.conv:to;
644                     assert(false, "Unknown key received ("~to!string(k)~")");
645                 }
646                 else
647                     return cast(HipKey)k;
648         }
649     }
650 }
651 else version(AppleOS)
652 {
653     public HipKey getHipKeyFromSystem(uint key)
654     {
655         switch(key)
656         {
657 
658             //Special Chars
659             case  0x31: return HipKey.SPACE; //space
660             case  0x24: return HipKey.ENTER; //returnKey
661             case  0x4C: return HipKey.ENTER; //enterKey
662             case  0x35: return HipKey.ESCAPE; //escape
663             case  0x38: return HipKey.SHIFT; //shift
664             case  0x37: return HipKey.ALT; //command
665             
666             //DPad Keys
667             case  0x7B: return HipKey.ARROW_LEFT; //leftArrow
668             case  0x7C: return HipKey.ARROW_RIGHT; //rightArrow
669             case  0x7D: return HipKey.ARROW_DOWN; //downArrow
670             case  0x7E: return HipKey.ARROW_UP; //upArrow
671             
672             //Alphabet
673             case  0x00: return HipKey.A; //a
674             case  0x0B: return HipKey.B; //b
675             case  0x08: return HipKey.C; //c
676             case  0x02: return HipKey.D; //d
677             case  0x0E: return HipKey.E; //e
678             case  0x03: return HipKey.F; //f
679             case  0x05: return HipKey.G; //g
680             case  0x04: return HipKey.H; //h
681             case  0x22: return HipKey.I; //i
682             case  0x26: return HipKey.J; //j
683             case  0x28: return HipKey.K; //k
684             case  0x25: return HipKey.L; //l
685             case  0x2E: return HipKey.M; //m
686             case  0x2D: return HipKey.N; //n
687             case  0x1F: return HipKey.O; //o
688             case  0x23: return HipKey.P; //p
689             case  0x0C: return HipKey.Q; //q
690             case  0x0F: return HipKey.R; //r
691             case  0x01: return HipKey.S; //s
692             case  0x11: return HipKey.T; //t
693             case  0x20: return HipKey.U; //u
694             case  0x09: return HipKey.V; //v
695             case  0x0D: return HipKey.W; //w
696             case  0x07: return HipKey.X; //x
697             case  0x10: return HipKey.Y; //y
698             case  0x06: return HipKey.Z; //z
699             
700             //Top Numbers
701             case  0x1D: return HipKey._0;//zero
702             case  0x12: return HipKey._1; //one
703             case  0x13: return HipKey._2;//two
704             case  0x14: return HipKey._3;//three
705             case  0x15: return HipKey._4;//four
706             case  0x17: return HipKey._5;//five
707             case  0x16: return HipKey._6;//six
708             case  0x1A: return HipKey._7;//seven
709             case  0x1C: return HipKey._8;//eight
710             case  0x19: return HipKey._9;//nine
711             
712             //Keypad Numbers
713             case  0x52: return HipKey._0; //keypad0
714             case  0x53: return HipKey._1; //keypad1
715             case  0x54: return HipKey._2; //keypad2
716             case  0x55: return HipKey._3; //keypad3
717             case  0x56: return HipKey._4; //keypad4
718             case  0x57: return HipKey._5; //keypad5
719             case  0x58: return HipKey._6; //keypad6
720             case  0x59: return HipKey._7; //keypad7
721             case  0x5B: return HipKey._8; //keypad8
722             case  0x5C: return HipKey._9; //keypad9
723             case  0xFF: return HipKey.NONE; //Invalid
724             default:
725                 // version(HipCheckUnknownKeycode)
726                 // {
727                 //     import hip.console.log;
728                 //     loglnError("Unknown key received ("~to!string(k)~")");
729                 //     assert(false, "Unknown key received ("~to!string(k)~")");
730                 // }
731                 // else
732                     return cast(HipKey)key;
733 
734         }
735     }
736 }
737 else version(PSVita)
738 {
739     public HipKey getHipKeyFromSystem(uint key){return HipKey._0;}
740 }